package org.oep.game;
import javax.microedition.lcdui.game.Sprite;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Graphics;
import java.util.Hashtable;
import java.io.IOException;


/**
 * An Actor is defined as a sprite that should move in some way or another.
 * @author pmkilgo
 *
 */
public class Actor {
	private String animationState = Actor.KEY_STAND;
	protected Point position = new Point();
	private Hashtable animations = new Hashtable();
	
	protected boolean widthSpecified = false, heightSpecified = false;
	protected int height = 0, width = 0;
	
	public static final int STAND_STILL = 0;
	public static final int WALK_UP = 1;
	public static final int WALK_DOWN = 2;
	public static final int WALK_LEFT = 3;
	public static final int WALK_RIGHT = 4;
	public static final int CUSTOM_STATE = 500;
	
	public Actor() {
		
	}
	
	public void paint(Graphics g) {
		paint(g, position.x, position.y);
	}
	
	public void paint(Graphics g, int a, int b) {
		if(currentSprite() == null)
			return;
		
		// For our purposes, just assume the sprite animation common pixel is bottom center
		
		currentSprite().setPosition(a - currentSprite().getWidth() / 2, b - currentSprite().getHeight());
		currentSprite().paint(g);
	}
	
	public void addAnimation(int state, String animKey, String spriteSheet, int frameX, int frameY) {
		Image im;
		try {
			im = ImageStore.getInstance().get(spriteSheet);
		} catch(IOException e) {
			im = Image.createImage(frameX, frameY);
			Graphics g = im.getGraphics();
			g.setColor(0xFF0000);
			g.drawLine(0, 0, frameX, frameY);
			g.drawLine(frameX, 0, 0, frameY);
		}
		Sprite s = new Sprite(im, frameX, frameY);
		Sprite r = new Sprite(im, frameX, frameY);
		r.setTransform(Sprite.TRANS_MIRROR);
		
		if(!heightSpecified) {
			height = s.getHeight();
			heightSpecified = true;
		}
		
		if(!widthSpecified) {
			width = s.getWidth();
			widthSpecified = true;
		}
			
		putSprite(animKey, s);
		
		// Decide if we need to put the mirrored sprite
		if(state == Actor.WALK_LEFT && getSprite(Actor.WALK_RIGHT) == null) {
			putSprite(Actor.KEY_WALK_RIGHT, r);
		}
		else if(state == Actor.WALK_RIGHT && getSprite(Actor.WALK_LEFT) == null) {
			putSprite(Actor.KEY_WALK_LEFT, r);
		}
	}
	
	public void setPosition(int x, int y) {
		this.position.x = x;
		this.position.y = y;
	}
	
	public void setAnimationState(String state) {
		if(this.animationState.compareTo(state) != 0) {
			// Reset current animation
			if(currentSprite() != null)
				currentSprite().setFrame(0);
			this.animationState = state;
		}
	}
	
	public void nextFrame() {
		if(currentSprite() != null)
			currentSprite().nextFrame();
	}

	public int getX() { return position.x; }
	public int getY() { return position.y; }
	
	public boolean isPlaying(String anim) {
		return animationState.compareTo(anim) == 0;
	}
	
	public int getHeight() {
		return height;
	}
	
	public int getWidth() {
		return width;
	}
	
	protected Sprite putSprite(String key, Sprite p) {
		return (Sprite) animations.put(key, p);
	}
	
	protected Sprite getSprite(int s) {
		return (Sprite) animations.get(new Integer(s));
	}
	
	protected Sprite currentSprite() {
		Sprite s = (Sprite) animations.get(animationState);
		if(s == null)
			return (Sprite) animations.get(Actor.KEY_STAND);
		else
			return s;
	}
	
	public boolean collidesWith(Actor other) {
		Sprite a = currentSprite();
		Sprite b = other.currentSprite();
		if(a == null || b == null) return false;
		
		return a.collidesWith(b, false);
	}
	
	public double distanceTo(Point p) {
		return position.distance(p);
	}
	
	public String toString() {
		return "Actor [" + animationState + "] ("+position.x+", "+position.y+")";
	}
	
	public int getFrame() {
		Sprite s = currentSprite();
		if(s == null) return 0;
		else return s.getFrame();
	}
	
	public int getFrameSequenceLength() {
		Sprite s = currentSprite();
		if(s == null) return 0;
		else return s.getFrameSequenceLength();
	}
	
	
	public static final String
		KEY_STAND = "STAND",
		KEY_WALK_UP = "WALK_UP",
		KEY_WALK_LEFT = "WALK_LEFT",
		KEY_WALK_RIGHT = "WALK_RIGHT",
		KEY_WALK_DOWN = "WALK_DOWN";
}
